Context2D = function (canvasId) {
	this.canvasId = canvasId;
	this.canvas = document.getElementById(canvasId);
	this.context = this.canvas.getContext("2d");
	this.fontSize = 17;
	this.fontFamily = "Arial";
	this.fillStyle = "rgba(255,255,255,.5)";
	this.textFillStyle = "black";
	this.strokeWidth = 2;
}
Context2D.prototype = p = Context2D.prototype;

p.translate = function (x, y) {
	this.context.translate (x, y);
}

p.beginPath = function () {
	this.context.beginPath();
}

p.moveTo = function (x, y) {
	this.context.moveTo (x, y);
}

p.lineTo = function (x, y) {
	this.context.lineTo (x, y);
}

p.closePath = function () {
	this.context.closePath();
}

p.fill = function () {
	this.context.fill ();
}

p.stroke = function () {
	this.context.stroke ();
}

p.setStrokeWidth = function (width) {
	this.strokeWidth = width;
	this.context.lineWidth = width;
}

p.measureText = function (text) {
	return new Size2D (this.context.measureText(text).width, this.fontSize);
}

p.fillText = function (text, x, y) {
	this.context.fillStyle = this.textFillStyle;
	this.context.fillText (text, x? x: 0, (y? y: 0) + this.fontSize);
	this.context.fillStyle = this.fillStyle;
}

p.setFont = function (size, family) {
	this.fontSize = size;
	this.fontFamily = family;
	this.context.font = size + "px " + family;
}

p.drawArrow = function (x1, y1, x2, y2, weight, color) {
	var ctx = this.context;
	if (color) {
		ctx.fillStyle = color;
	}
	var dir = new Vector2D(x2 - x1, y2 - y1).normalize();
	var normal = dir.getNormal();
	ctx.beginPath();
	ctx.moveTo(x1, y1);
	ctx.lineTo(x2, y2);
	ctx.stroke();
	ctx.beginPath();
	ctx.moveTo(x1, y1);
	ctx.lineTo(x1 + (dir.x + normal.x / 2) * weight, y1 + (dir.y + normal.y / 2) * weight);
	ctx.lineTo(x1 + (dir.x + normal.x / 2) * weight, y1 + (dir.y - normal.y / 2) * weight);
	ctx.closePath();
	ctx.fill();
	ctx.stroke();
	if (color) {
		ctx.fillStyle = this.fillStyle;
	}
};

p.circle = function(x, y, radius){
	var ctx = this.context;
	ctx.arc(x, y, radius, 0 , 2 * Math.PI, false);
};

p.setFillStyle = function (style) {
	this.fillStyle = style;
	this.context.fillStyle = style;
}

p.setTextFillStyle = function (style) {
	this.textFillStyle = style;
}

p.reset = function () {
	this.setFont(this.fontSize, this.fontFamily);
	this.setFillStyle(this.fillStyle);
	this.setTextFillStyle(this.textFillStyle);
	this.setStrokeWidth(this.strokeWidth);
}

Size2D = function (width, height) {
	this.width = width;
	this.height = height;
}

Size2D.prototype.addHorizontally = function (size, times) {
	this.width += size.width * (times == undefined? 1: times);
	this.height = Math.max(this.height, size.height);
	return this;
}

Size2D.prototype.addVertically = function (size, times) {
	this.width = Math.max(this.width, size.width);
	this.height += size.height * (times == undefined? 1: times);
	return this;
}

Size2D.prototype.copy = function () {
	return new Size2D (this.width, this.height);
}

Vector2D = function (x, y) {
	this.x = x;
	this.y = y;
}

Vector2D.prototype.normalize = function () {
	len = Math.sqrt(this.x * this.x + this.y * this.y);
	this.x /= len;
	this.y /= len;
	return this;
}

Vector2D.prototype.getNormal = function () {
	return new Vector2D(-this.y, this.x);
}
